<script setup lang="ts">
import { usePrefix } from '@season-designable/vue';
import { ElButton } from 'element-plus';
import { computed, ref, watch } from 'vue';
import { PolyType, PolyTypes } from './types';
import { isEmpty } from 'lodash-es';

const props = defineProps(['value', 'exclude', 'include', 'polyTypes']);
const emit = defineEmits(['change']);
const prefix = usePrefix('poly-input');
const typesValue = ref<any>({});

const createTypes = (
  types: PolyTypes,
  exclude: string[],
  include: string[]
) => {
  return types.filter(({ type }) => {
    if (Array.isArray(include) && include.length) {
      return include.includes(type);
    }
    if (Array.isArray(exclude) && exclude.length) {
      return !exclude.includes(type);
    }
    return true;
  });
};

const types = createTypes(props.polyTypes, props.exclude, props.include);

const current = ref(types?.[0]?.type);
const type = computed(() => types?.find(({ type }) => type === current.value));

watch(
  () => props.value,
  () => {
    types?.forEach(({ checker, type }) => {
      if (checker && checker(props.value)) {
        current.value = type;
      }
    });
  },
  { immediate: true }
);

const transformOnChangeValue = (value: any, type?: PolyType) => {
  return type?.toChangeValue ? type?.toChangeValue(value) : value;
};

const getEventValue = (event: any) => {
  if (event?.target) {
    if (!isEmpty(event.target.value)) return event.target.value;
    if (!isEmpty(event.target.checked)) return event.target.checked;
    return;
  }
  return event;
};

const onChange = (e: any) => {
  const value = getEventValue(e);
  if (type.value?.type) {
    typesValue.value[type.value?.type] = e;
  }

  emit('change', transformOnChangeValue(value, type.value));
};

const onClick = () => {
  const currentIndex = types?.findIndex(({ type }) => type === current.value);
  const nextIndex = (currentIndex + 1) % types?.length;
  const nextType = types[nextIndex];

  if (nextType === type.value) return;

  current.value = nextType.type;

  emit(
    'change',
    transformOnChangeValue(typesValue.value[nextType?.type], nextType)
  );
};
</script>

<template>
  <div :class="prefix">
    <template v-if="type?.component">
      <div :class="prefix + '-content'">
        <type.component
          :value="
            type?.toInputValue ? type?.toInputValue(props.value) : props.value
          "
          @change="onChange"
        >
        </type.component>
      </div>
    </template>

    <ElButton
      :class="prefix + '-controller'"
      :style="{
        width: !type?.component ? '100%' : 'auto',
      }"
      @click="onClick"
    >
      {{ type?.title || type?.type }}
    </ElButton>
  </div>
</template>

<style lang="scss" scoped>
@import '../../../../styles.scss';
.dn-poly-input {
  display: flex;
  width: 100%;
  align-items: center;

  .dn-poly-input-content {
    flex-grow: 2;
    margin-right: 2px;
    display: flex;

    .#{$element-prefix}-select {
      width: 100%;
    }

    .#{$element-prefix}-input-number {
      width: 100%;
    }
  }

  .dn-poly-input-controller {
    border: 1px solid #{$border-color-base};
    border-radius: 2px;
    cursor: pointer;
    padding: 0 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-grow: 0;
  }
}
</style>
